{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 第一个聊天机器人"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 简单进行一个机器翻译样例\n",
    "from langchain.chat_models import ChatOpenAI # 导入ChatOpenAI类，以访问由vllm提供的OpenAI API\n",
    "# 导入Messages类\n",
    "from langchain.schema import (\n",
    "    AIMessage,\n",
    "    HumanMessage,\n",
    "    SystemMessage\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='我喜欢编程。')"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建一个ChatOpenAI对象\n",
    "chat = ChatOpenAI(\n",
    "    streaming=True,\n",
    "    verbose=True,\n",
    "    openai_api_key=\"none\", # 这里由于我们使用的是vllm本地LLM的API，所以填写none\n",
    "    openai_api_base=\"http://127.0.0.1:8000/v1\",\n",
    "    model_name=\"Qwen/Qwen1.5-4B-Chat\",\n",
    "    temperature=0\n",
    ") \n",
    "chat.predict_messages([\n",
    "    HumanMessage(\n",
    "        content=(\"Translate this sentence from English to Chinese.\"\n",
    "                 \"I love programming.\")\n",
    "    )\n",
    "])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 提示词模板"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[SystemMessage(content='You are a helpful assistant that translates English toChinese'),\n",
       " HumanMessage(content='I love programming.')]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用MessagePromptTemplate来创建一个提示词模板\n",
    "from langchain.prompts.chat import (\n",
    "    ChatPromptTemplate,\n",
    "    SystemMessagePromptTemplate,\n",
    "    HumanMessagePromptTemplate,\n",
    ")\n",
    "# 通过“留槽”的方式来创建一个模板\n",
    "template = (\n",
    "    \"You are a helpful assistant that translates {input_language} to\"\n",
    "    \"{output_language}\"\n",
    ")\n",
    "# 创建系统提示词模板\n",
    "system_message_prompt = SystemMessagePromptTemplate.from_template(template)\n",
    "# 创建用户输入提示词模板\n",
    "human_template = \"{text}\"\n",
    "\n",
    "human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)\n",
    "# 创建一个聊天提示词模板\n",
    "chat_prompt = ChatPromptTemplate.from_messages(\n",
    "    [\n",
    "        system_message_prompt,\n",
    "        human_message_prompt,\n",
    "    ]\n",
    ")\n",
    "# Langchain将自动检索所有Messages中预留的格式化输出槽，因此我们只需要像设置参数一样把提示词输入进去即可了\n",
    "chat_prompt.format_messages(\n",
    "    input_language=\"English\",\n",
    "    output_language=\"Chinese\",\n",
    "    text=\"I love programming.\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 创建第一个链"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'我热爱编程。'"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 导入LLMChain类\n",
    "from langchain import LLMChain\n",
    "\n",
    "# 定义一个链\n",
    "chain = LLMChain(llm=chat, prompt=chat_prompt)\n",
    "# 运行链\n",
    "chain.run(\n",
    "    input_language=\"English\",\n",
    "    output_language=\"Chinese\",\n",
    "    text=\"I love programming.\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 创建第一个智能体(Agent)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ['SERPAPI_API_KEY'] = \"<YOUR_SERPAPI_KEY>\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Looking in indexes: https://mirrors.ustc.edu.cn/pypi/web/simple\n",
      "Requirement already satisfied: google-search-results in /home/elin/anaconda3/envs/langchain/lib/python3.11/site-packages (2.4.2)\n",
      "Requirement already satisfied: requests in /home/elin/anaconda3/envs/langchain/lib/python3.11/site-packages (from google-search-results) (2.31.0)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in /home/elin/anaconda3/envs/langchain/lib/python3.11/site-packages (from requests->google-search-results) (3.3.2)\n",
      "Requirement already satisfied: idna<4,>=2.5 in /home/elin/anaconda3/envs/langchain/lib/python3.11/site-packages (from requests->google-search-results) (3.6)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in /home/elin/anaconda3/envs/langchain/lib/python3.11/site-packages (from requests->google-search-results) (2.2.0)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /home/elin/anaconda3/envs/langchain/lib/python3.11/site-packages (from requests->google-search-results) (2024.2.2)\n",
      "Looking in indexes: https://mirrors.ustc.edu.cn/pypi/web/simple\n",
      "Collecting numexpr\n",
      "  Downloading https://mirrors.bfsu.edu.cn/pypi/web/packages/99/f0/1337b186b5213f61302d57813387e877e6d65ac094a3ea2515dbf2c7d485/numexpr-2.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (377 kB)\n",
      "\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m377.5/377.5 kB\u001b[0m \u001b[31m11.9 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
      "\u001b[?25hRequirement already satisfied: numpy>=1.13.3 in /home/elin/anaconda3/envs/langchain/lib/python3.11/site-packages (from numexpr) (1.26.4)\n",
      "Installing collected packages: numexpr\n",
      "Successfully installed numexpr-2.9.0\n"
     ]
    }
   ],
   "source": [
    "# 为了确保搜索的可用性，请安装google-search-results和numexpr\n",
    "!pip install google-search-results\n",
    "!pip install numexpr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3mThought: I need to find out the weather in Shenyang three days from now. I can use the search engine to do this.\n",
      "Action:\n",
      "```\n",
      "{\n",
      "  \"action\": \"Search\",\n",
      "  \"action_input\": \"weather in Shenyang three days from now\"\n",
      "}\n",
      "```\u001b[0m\n",
      "Observation: \u001b[36;1m\u001b[1;3m{'type': 'weather_result', 'temperature': '36', 'unit': 'Fahrenheit', 'precipitation': '0%', 'humidity': '25%', 'wind': '13 mph', 'location': 'Shenyang, Liaoning, China', 'date': 'Tuesday', 'weather': 'Mostly cloudy'}\u001b[0m\n",
      "Thought:\u001b[32;1m\u001b[1;3mI now know the final answer\n",
      "Final Answer: According to the weather forecast, it will be mostly cloudy in Shenyang three days from now with a temperature of 36°F and a humidity of 25%. The wind speed is 13 mph.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'According to the weather forecast, it will be mostly cloudy in Shenyang three days from now with a temperature of 36°F and a humidity of 25%. The wind speed is 13 mph.'"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 加载智能体需要的工具\n",
    "from langchain.agents import (\n",
    "    load_tools,\n",
    "    initialize_agent,\n",
    "    AgentType,\n",
    ")\n",
    "# 加载工具\n",
    "tools = load_tools(['serpapi','llm-math'],llm=chat)\n",
    "\n",
    "# 初始化智能体\n",
    "agent = initialize_agent(tools,chat,agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,verbose=True)\n",
    "\n",
    "# 运行智能体\n",
    "agent.run(\n",
    "    \"What will be weather in Shenyang three days from now?\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 记忆组件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入对话链\n",
    "from langchain.chains import ConversationChain\n",
    "# 导入MessagePlaceHolder\n",
    "from langchain.prompts import MessagesPlaceholder\n",
    "# 导入记忆组件\n",
    "from langchain.memory import ConversationBufferMemory\n",
    "\n",
    "# 创建新的Message\n",
    "prompt = ChatPromptTemplate.from_messages([\n",
    "    SystemMessagePromptTemplate.from_template(\n",
    "        \"\"\"\n",
    "        The following is a friendly conversation between a human and an AI.\n",
    "        The AI istalkative and provides lots of specific details from its context.\n",
    "        If the AI does not know the answer to a question,it truthfully says it does not know.\n",
    "        \"\"\"\n",
    "    ),\n",
    "    MessagesPlaceholder(variable_name=\"history\"),\n",
    "    HumanMessagePromptTemplate.from_template(\"{input}\"),\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建一个对话记忆组件\n",
    "memory = ConversationBufferMemory(return_messages=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建一个对话链\n",
    "conversation = ConversationChain(memory=memory,prompt=prompt,llm=chat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'你好，大霖！很高兴能和你聊天。有什么我可以帮助你的吗？'"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"你好，我是大霖！\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langchain",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
